package com.jfinal.weixin.mvc;

/**
 * @author LarryKoo(larrykoo@126.com)
 * @date 2015-12-13
 */

import com.jfinal.utils.Exceptions;
import com.jfinal.weixin.kit.XStreamFactory;
import com.jfinal.weixin.msg.InMsgParser;
import com.jfinal.weixin.msg.WeixinConfig;
import com.jfinal.weixin.msg.in.*;
import com.jfinal.weixin.msg.in.event.*;
import com.jfinal.weixin.msg.out.*;
import com.thoughtworks.xstream.XStream;
import lombok.extern.slf4j.Slf4j;

/**
 * InMsg, 处理工具并分发到相应的处理方法
 */
@Slf4j
public class WeChatKit {

    /**
     * 默认的消息处理器
     */
    private static MessageProcessingHandler defHandler = new DefaultMessageProcessingHandler();

    /**
     * 处理返回消息, 得到返回微信公众平台的消息数据
     *
     * @param inMsgXml 解密之后的微信消息体
     * @param wxConfig 包含帐号信息的微信帐号对象
     * @return
     */
    public static String processing(String inMsgXml, WeixinConfig wxConfig) {
        String resXml = "";
        MessageProcessingHandler msgHandler = wxConfig.getMessageHandler();

        //解析xml数据为InMsg对象
        InMsg inMsg = InMsgParser.parse(inMsgXml);
        OutMsg outMsg = null;

        if (msgHandler == null) {
            msgHandler = defHandler;
        }

        try {
            //取得消息类型
//        String type = inMsg.getMsgType();

            msgHandler.beforeProcess(inMsg);    //消息进入处理

            /**
             * 处理各种消息类型
             */
            if (inMsg instanceof InTextMsg) {
                msgHandler.processInTextMsg((InTextMsg) inMsg);
            } else if (inMsg instanceof InImageMsg) {
                msgHandler.processInImageMsg((InImageMsg) inMsg);
            } else if (inMsg instanceof InVoiceMsg) {
                msgHandler.processInVoiceMsg((InVoiceMsg) inMsg);
            } else if (inMsg instanceof InVideoMsg) {
                msgHandler.processInVideoMsg((InVideoMsg) inMsg);
            } else if (inMsg instanceof InLocationMsg) {
                msgHandler.processInLocationMsg((InLocationMsg) inMsg);
            } else if (inMsg instanceof InLinkMsg) {
                msgHandler.processInLinkMsg((InLinkMsg) inMsg);
            } else if (inMsg instanceof InMenuEvent) {
                msgHandler.processInMenuEvent((InMenuEvent) inMsg);
            } else if (inMsg instanceof InCustomEvent) {
                msgHandler.processInCustomEvent((InCustomEvent) inMsg);
            } else if (inMsg instanceof InFollowEvent) {
                msgHandler.processInFollowEvent((InFollowEvent) inMsg);
            } else if (inMsg instanceof InScanEvent) {
                msgHandler.processInQrCodeEvent((InScanEvent) inMsg);
            } else if (inMsg instanceof InLocationEvent) {
                msgHandler.processInLocationEvent((InLocationEvent) inMsg);
            } else if (inMsg instanceof InMassEvent) {
                msgHandler.processInMassEvent((InMassEvent) inMsg);
            } else if (inMsg instanceof InTemplateMsgEvent) {
                msgHandler.processInTemplateMsgEvent((InTemplateMsgEvent) inMsg);
            } else if (inMsg instanceof InShakeAroundUserShakeEvent) {
                msgHandler.processInShakeAroundUserShakeEvent((InShakeAroundUserShakeEvent) inMsg);
            } else {
                log.error("未能识别的消息类型,消息xml内容为:\n {}", inMsgXml);
            }

            /**
             * 得到OutMsg对象
             */
            outMsg = msgHandler.getOutMessage();

            msgHandler.afterProcess(inMsg, outMsg);     //消息业务逻辑完成后的处理

            outMsg = msgHandler.getOutMessage();

        } catch (Exception e) {
            log.debug("消息驱动异常:{}", e);
            throw Exceptions.unchecked(e);
        } finally {
            if (outMsg != null) {
                // 把发送发送对象转换为xml输出
                XStream xs = XStreamFactory.ice.init(true);
                xs.autodetectAnnotations(true);     //自动侦查注解
                xs.alias("xml", outMsg.getClass());
                xs.alias("item", Article.class);
                resXml = xs.toXML(outMsg);
            }
            return resXml;
        }
    }
}
